﻿// {$DEFINE MSSQL}
unit UModel;

interface

uses
  DataLayer, System.SysUtils,
  System.Classes, Data.FMTBcd, Data.DB, FMX.Grid,
  Data.SqlExpr, System.Generics.Collections;

type

  // declare the Interface to display a page items on buttons
  IDispAPageItemsProc = Interface
    procedure DisplayAPageMenuItems(page: integer);
    procedure DisplayAPageCategoryItems(page: integer);
    procedure DisplayAPageInstructionItems(page: integer);

  End;

  TPriceType = (Normal, Weekend, HappyHour);

  TProfile = class
  private
    FPriceType: TPriceType;
  public
    ForceVIPDiscount: boolean;
    NotAllowModify: boolean;
    RoundingFlag: smallint;
    ServiceChargeRate: double;
    HappyHour: boolean;
    HappyHourStartTime: TDatetime;
    HappyHourEndTime: TDatetime;
    EnableWeekendPriceFunction: boolean;
    WeekendPriceStartDay: integer;
    WeekendPriceEndDay: integer;
    property PriceType: TPriceType read FPriceType;
    constructor Create;
  end;

  TMenuItem = class
  public
    Code, Description, Category: String;
    PriceList: TList<TPair<String, Currency>>;
    TaxRate: double;
    constructor Create(q: TSQLQuery);
  end;

  TPagingObject<T: class> = class(TObject)
  private
  protected
    FDisplayAPageProc: IDispAPageItemsProc;
    CurrentPage: integer;
    LastPage: integer;
    ItemNumberPerPage: integer;
    procedure LoadItems; virtual; abstract;
    procedure RefreshUI; virtual; abstract;
    procedure CalcLastPage;
  public
    List: TList<T>;
    procedure NextPage;
    procedure PreviousPage;
    procedure FirstPage;
    function SelectAnItem(key: string): T;
    constructor Create(ItemNumberPerPage: integer;
      DisplayAPageProc: IDispAPageItemsProc);
    destructor Destroy; override;
    property DisplayAPageMenuProc: IDispAPageItemsProc read FDisplayAPageProc
      write FDisplayAPageProc;
  end;

  TCategoryItem = class
  public
    Category: String;
    constructor Create(Category: string);
   // destructor Destroy; override;
  end;

  TMenu<T> = class(TPagingObject<TMenuItem>)
  private
    CurrrentCategory: String;
    procedure FindItemsByCategory;
  protected
    procedure LoadItems; override;
    procedure RefreshUI; override;
  public
    TotalItemList: TList<TMenuItem>;
    procedure ChangeCategory(Category: String);
    Constructor Create(ItemNumberPerPage: integer;
      DisplayAPageProc: IDispAPageItemsProc);
  end;

  TMenuInstructionLink = class
  public
    ParentCode, ChildCode, Description: string;
    Instruction, ChoiceItem, MaximunCharge: boolean;
    SalesPrice, SalesQty: double;
    Constructor Create(q: TSQLQuery);
    // class function GetMenuInstructionLinkList:TList<TMenuInstructionLink>;
  end;

  TInstruction<T> = class(TPagingObject<TMenuInstructionLink>)
  private
    ItemCode: String;
    procedure FindLinksByItemCode;
  protected
    procedure LoadItems; override;
    procedure RefreshUI; override;
  public
    TotalInstructionList: TList<TMenuInstructionLink>;
    procedure ChangeItem(ItemCode: String);
    Constructor Create(ItemNumberPerPage: integer;
      DisplayAPageProc: IDispAPageItemsProc);
  end;

  TCategory<T> = class(TPagingObject<TCategoryItem>)
  protected
    procedure LoadItems; override;
    procedure RefreshUI; override;
  public

  end;

  { TOrderListItem = class
    public
    protected
    private
    ID : Integer;
    Description : string;
    Qty : Integer;
    Price : Double;
    Amount : Double;
    Discount : Double;
    end; }

  TOrderItem = class
  public
    // Declare the fields which will be inserted into OrderI Table
    FCondition: integer;
    FPaidQty: double;
    FPriceSelect: double;
    FSeat: integer;
    FOrderNo: String;
    FItemCode: String;
    FQty: double;
    FPrice: double;
    FDiscount: double;
    FTaxRate: double;
    FIDNo: integer;
    FPrintFlag: boolean;
    FSentToKitchen: boolean;
    FVoidReason: String;
    FSpecialOrder: String;
    FCheckListPrinted: boolean;
    FVoidFlag: boolean;
    FOrderOperator: String;
    FOriginalPrice: double;
    FPresetDiscountCode: String;
    FDescription: String;
    FItemNumber: String;

    property Condition: integer read FCondition write FCondition;
    property PaidQty: double read FPaidQty write FPaidQty;
    property PriceSelect: double read FPriceSelect write FPriceSelect;
    property Seat: integer read FSeat write FSeat;
    property OrderNo: String read FOrderNo write FOrderNo;
    property ItemCode: String read FItemCode write FItemCode;
    property Qty: double read FQty write FQty;
    property Price: double read FPrice write FPrice;
    property Discount: double read FDiscount write FDiscount;
    property TaxRate: double read FTaxRate write FTaxRate;
    property IDNo: integer read FIDNo write FIDNo;
    property PrintFlag: boolean read FPrintFlag write FPrintFlag;
    property SentToKitchen: boolean read FSentToKitchen write FSentToKitchen;
    property VoidReason: String read FVoidReason write FVoidReason;
    property SpecialOrder: String read FSpecialOrder write FSpecialOrder;
    property CheckListPrinted: boolean read FCheckListPrinted
      write FCheckListPrinted;
    property VoidFlag: boolean read FVoidFlag write FVoidFlag;
    property OrderOperator: String read FOrderOperator write FOrderOperator;
    property OriginalPrice: double read FOriginalPrice write FOriginalPrice;
    property PresetDiscountCode: String read FPresetDiscountCode
      write FPresetDiscountCode;
    property Description: String read FDescription write FDescription;
    property ItemNumber: String read FItemNumber write FItemNumber;
  end;

  TOrder = class
  public

    TDataModule: TDataModule1;
    // Declare the fields which will be inserted into OrderH Table
    FBookingNo: String;
    FCredit: boolean;
    FOrderPrinted: boolean;
    FTips: double;
    FOrderDate: TDatetime;
    FOrderNo: String;
    FPersons: integer;
    FTableNo: String;
    FServicePerson: String;
    FAmount: double;
    FGST: double;
    FPaidAmount: double;
    FInvoiceNo: String;
    FVipNo: integer;
    FVipName: String;
    FOpName: String;
    FServiceCharge: double;
    FServiceChargeRate: double;
    FSurcharge: double;
    FMachineID: String;
    FBillKind: integer;
    FDollarDiscount: double;
    FDueTime: TDatetime;
    FDiscountKind: integer;
    FDelivery: boolean;
    FOtherCharge: double;
    FOtherChargeRate: double;
    FPriceIncludeGST: boolean;
    FCurrentGSTRate: double;
    FRewardPoints: double;
    FSplitBill: boolean;
    FCustomerName: String;
    FDiscountOperator: String;
    OrderItemList: TList<TOrderItem>;

    property BookingNo: string read FBookingNo write FBookingNo;
    property Credit: boolean read FCredit write FCredit;
    property OrderPrinted: boolean read FOrderPrinted write FOrderPrinted;
    property Tips: double read FTips write FTips;
    property OrderDate: TDatetime read FOrderDate write FOrderDate;
    property OrderNo: string read FOrderNo write FOrderNo;
    property Persons: integer read FPersons write FPersons;
    property TableNo: string read FTableNo write FTableNo;
    property ServicePerson: string read FServicePerson write FServicePerson;
    property Amount: double read FAmount write FAmount;
    property GST: double read FGST write FGST;
    property PaidAmount: double read FPaidAmount write FPaidAmount;
    property InvoiceNo: string read FInvoiceNo write FInvoiceNo;
    property VipNo: integer read FVipNo write FVipNo;
    property VipName: string read FVipName write FVipName;
    property OpName: string read FOpName write FOpName;
    property ServiceCharge: double read FServiceCharge write FServiceCharge;
    property Surcharge: double read FSurcharge write FSurcharge;
    property MachineID: String read FMachineID write FMachineID;
    property BillKind: integer read FBillKind write FBillKind;
    property DollarDiscount: double read FDollarDiscount write FDollarDiscount;
    property DueTime: TDatetime read FDueTime write FDueTime;
    property DiscountKind: integer read FDiscountKind write FDiscountKind;
    property Delivery: boolean read FDelivery write FDelivery;
    property OtherCharge: double read FOtherCharge write FOtherCharge;
    property OtherChargeRate: double read FOtherChargeRate
      write FOtherChargeRate;
    property PriceIncludeGST: boolean read FPriceIncludeGST
      write FPriceIncludeGST;
    property CurrentGSTRate: double read FCurrentGSTRate write FCurrentGSTRate;
    property RewardPoints: double read FRewardPoints write FRewardPoints;
    property SplitBill: boolean read FSplitBill write FSplitBill;
    property CustomerName: string read FCustomerName write FCustomerName;
    property DiscountOperator: string read FDiscountOperator
      write FDiscountOperator;

    // Created: TDateTime;
    procedure AddanOrderList(striGrid: TStringGrid; TableNo: String);

  end;

  TTable = class
  private
    FPageNo: integer;
    FX: integer;
    FY: integer;
    FWidth: integer;
    FHeight: integer;
    FTableNo: string;
    FShape: integer;
    FOrderNo: string;
    FDescription: string;
    FIsTable: boolean;

  const
    Rate = 1.3;
  public
    property PageNo: integer read FPageNo;
    property X: integer read FX;
    property Y: integer read FY;
    property Width: integer read FWidth;
    property Height: integer read FHeight;
    property TableNo: string read FTableNo;
    property Shape: integer read FShape;
    property OrderNo: string read FOrderNo write FOrderNo;
    property Description: string read FDescription;
    property IsTable: boolean read FIsTable;
    constructor Create(TableNo, OrderNo, Description: string;
      PageNo, X, Y, Width, Height, Shape: integer; PropertyFlag: integer);
  end;

  TCustomer = class
  private
    FVipNo, FVipName, ftele, fstreetno, faddress, fsuburb, fpostcode: String;
  public
    property VipNo: string read FVipNo write FVipNo;
    property VipName: string read FVipName write FVipName;
    property tele: string read ftele write ftele;
    property streetno: string read fstreetno write fstreetno;
    property address: string read faddress write faddress;
    property suburb: string read fsuburb write fsuburb;
    property postcode: string read fpostcode write fpostcode;
    constructor Create(VipNo: string; VipName: string; tele: string;
      streetno: string; address: string; suburb: string; postcode: string);

  end;

  TCustomerInfo = class
  public
    CustomerList: TList<TCustomer>;
    constructor Create;
    destructor Destroy;

  end;

  TTablePage = class
  private
    FPageNo: integer;
    FDescription: String;
    FTables: TList<TTable>;
  public
    property PageNo: integer read FPageNo;
    property Description: String read FDescription;
    property Tables: TList<TTable> read FTables;
    constructor Create(PageNo: integer; Description: string);
  end;

  TTablePageList = class
  private
    FTablePageList: TList<TTablePage>;
    SelectedPageNo: integer;
    SelectedTableNo: string;
    procedure LoadPages;
    procedure LoadTables;
    function GetTablePageItem(PageNo: integer): TTablePage;
  public
    property TablePageList: TList<TTablePage> read FTablePageList;
    procedure SelectATable(PageNo: integer; TableNo: string);
    constructor Create;
  end;

  TOrderItemList = class

  end;

var
  Profile: TProfile;
  OrderList: TList<TOrder>;

implementation

{$REGION 'TPagingObject' }

function TPagingObject<T>.SelectAnItem(key: string): T;
begin
end;

procedure TPagingObject<T>.FirstPage;
begin
  CurrentPage := 1;
  RefreshUI;
end;

procedure TPagingObject<T>.PreviousPage;
begin
  if CurrentPage > 1 then
  begin
    CurrentPage := CurrentPage - 1;
    RefreshUI;
  end;
end;

procedure TPagingObject<T>.NextPage;
begin
  if CurrentPage < LastPage then
  begin
    CurrentPage := CurrentPage + 1;
    RefreshUI;
  end;
end;

procedure TPagingObject<T>.CalcLastPage;
begin
  self.LastPage := List.Count div self.ItemNumberPerPage;
  if (List.Count mod self.ItemNumberPerPage) > 0 then
    LastPage := LastPage + 1;
end;

constructor TPagingObject<T>.Create(ItemNumberPerPage: integer;
  DisplayAPageProc: IDispAPageItemsProc);
begin
  inherited Create;
  self.FDisplayAPageProc := DisplayAPageProc;
  self.ItemNumberPerPage := ItemNumberPerPage;
  List := TList<T>.Create;
  LoadItems;
end;

destructor TPagingObject<T>.Destroy;
begin
  List.Free;
  inherited Destroy;
end;

{$ENDREGION}
{$REGION 'TOrder'}

procedure TOrder.AddanOrderList(striGrid: TStringGrid; TableNo: String);
var
  OrderItem: TOrderItem;
  Order: TOrder;
begin
  OrderItem.FItemNumber := striGrid.Cells[0, 0];
  OrderItem.FDescription := striGrid.Cells[1, 0];

  Order.FTableNo := TableNo;
  OrderList.Add(Order);

  OrderItemList.Add(OrderItem);

end;
{$ENDREGION}
{$REGION 'TMenu' }

procedure TMenu<T>.ChangeCategory(Category: String);
begin
  if (Category <> self.CurrrentCategory) then
  begin
    self.CurrrentCategory := Category;
    FindItemsByCategory;
    self.CalcLastPage;
    FirstPage;
  end;
end;

procedure TMenu<T>.FindItemsByCategory;
var
  i: integer;
begin
  self.List.Clear;
  for i := 0 to self.TotalItemList.Count - 1 do
  begin
    if self.CurrrentCategory = TotalItemList.Items[i].Category then
      List.Add(TotalItemList.Items[i])
  end;
end;

procedure TMenu<T>.LoadItems;
var
  q: TSQLQuery;
begin
  q := DataModule1.GetMenuItems;
  while not q.eof do
  begin
    TotalItemList.Add(TMenuItem.Create(q));
    q.Next;
  end;
  q.Close;
end;

procedure TMenu<T>.RefreshUI;
begin
  DisplayAPageMenuProc.DisplayAPageMenuItems(CurrentPage);
end;

constructor TMenu<T>.Create(ItemNumberPerPage: integer;
  DisplayAPageProc: IDispAPageItemsProc);
begin
  self.TotalItemList := TList<TMenuItem>.Create;
  inherited Create(ItemNumberPerPage, DisplayAPageProc);
end;
{$ENDREGION}
{$REGION 'TInstruction' }

procedure TInstruction<T>.ChangeItem(ItemCode: String);
begin
  if (ItemCode <> self.ItemCode) then
  begin
    self.ItemCode := ItemCode;
    FindLinksByItemCode;
    if List.Count > 0 then
    begin
      self.CalcLastPage;
      FirstPage;
    end;
  end;
end;

procedure TInstruction<T>.FindLinksByItemCode;
var
  i: integer;
begin
  self.List.Clear;
  for i := 0 to self.TotalInstructionList.Count - 1 do
  begin
    if self.ItemCode = TotalInstructionList.Items[i].ParentCode then
      List.Add(TotalInstructionList.Items[i])
  end;
end;

procedure TInstruction<T>.LoadItems;
var
  q: TSQLQuery;
begin
  q := DataModule1.GetMenuInstructionLink;
  while not q.eof do
  begin
    TotalInstructionList.Add(TMenuInstructionLink.Create(q));
    q.Next;
  end;
  q.Close;
end;

procedure TInstruction<T>.RefreshUI;
begin
  DisplayAPageMenuProc.DisplayAPageInstructionItems(CurrentPage);
end;

constructor TInstruction<T>.Create(ItemNumberPerPage: integer;
  DisplayAPageProc: IDispAPageItemsProc);
begin
  self.TotalInstructionList := TList<TMenuInstructionLink>.Create;
  inherited Create(ItemNumberPerPage, DisplayAPageProc);
end;
{$ENDREGION}
{$REGION 'TCategory' }

constructor TCategoryItem.Create(Category: string);
begin
  inherited Create;
  self.Category := Category;
end;

procedure TCategory<T>.LoadItems;
var
  q: TSQLQuery;
begin
  // DataModule := TDataModule1.Create(nil);
  q := DataModule1.GetCategoryItems;

  while not q.eof do
  begin
    List.Add(TCategoryItem.Create(q.FieldByName('category').asstring));
    q.Next;
  end;
  q.Close;
  CalcLastPage;
end;

procedure TCategory<T>.RefreshUI;
begin
  DisplayAPageMenuProc.DisplayAPageCategoryItems(CurrentPage);
end;
{$ENDREGION}
{$REGION 'TMenuItem'}

constructor TMenuItem.Create(q: TSQLQuery);
var
  Multiple: boolean;
begin
  inherited Create;
  self.Code := q.FieldByName('ItemCode').asstring;
  self.Category := q.FieldByName('Category').asstring;
  self.Description := q.FieldByName('Description1').asstring;
  self.TaxRate := q.FieldByName('TaxRate').AsCurrency;
{$IFDEF MSSQL}
  Multiple := q.FieldByName('Multiple').AsBoolean;
{$ELSE}
  Multiple := q.FieldByName('Multiple').AsInteger = 1;
{$ENDIF}
  self.PriceList := TList < TPair < String, Currency >>.Create;
  if Profile.PriceType = TPriceType.Normal then // add normal prices to list
  begin
    if not Multiple then
      PriceList.Add(TPair<String, Currency>.Create(q.FieldByName('Description1')
        .asstring, q.FieldByName('Price').AsCurrency))
    else
    begin
      if q.FieldByName('SubDescription').asstring = '' then
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('Description1').asstring, q.FieldByName('Price')
          .AsCurrency))
      else
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('SubDescription').asstring, q.FieldByName('Price')
          .AsCurrency));

      if q.FieldByName('SubDescription1').asstring <> '' then
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('SubDescription1').asstring, q.FieldByName('Price1')
          .AsCurrency));

      if q.FieldByName('SubDescription2').asstring <> '' then
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('SubDescription2').asstring, q.FieldByName('Price2')
          .AsCurrency));

      if q.FieldByName('SubDescription3').asstring <> '' then
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('SubDescription3').asstring, q.FieldByName('Price3')
          .AsCurrency));
    end;
  end
  else if Profile.PriceType = TPriceType.Weekend then
  // add weekend prices to list
  begin
    if not Multiple then
      PriceList.Add(TPair<String, Currency>.Create(q.FieldByName('Description1')
        .asstring, q.FieldByName('WeekendPrice').AsCurrency))
    else
    begin
      if q.FieldByName('SubDescription').asstring = '' then
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('Description1').asstring, q.FieldByName('WeekendPrice')
          .AsCurrency))
      else
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('SubDescription').asstring,
          q.FieldByName('WeekendPrice').AsCurrency));

      if q.FieldByName('SubDescription1').asstring <> '' then
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('SubDescription1').asstring,
          q.FieldByName('WeekendPrice1').AsCurrency));

      if q.FieldByName('SubDescription2').asstring <> '' then
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('SubDescription2').asstring,
          q.FieldByName('WeekendPrice2').AsCurrency));

      if q.FieldByName('SubDescription3').asstring <> '' then
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('SubDescription2').asstring,
          q.FieldByName('WeekendPrice3').AsCurrency));
    end;
  end
  else //
  begin
    if not Multiple then
      PriceList.Add(TPair<String, Currency>.Create(q.FieldByName('Description1')
        .asstring, q.FieldByName('HappyHourPrice1').AsCurrency))
    else
    begin
      if q.FieldByName('SubDescription').asstring = '' then
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('Description1').asstring,
          q.FieldByName('HappyHourPrice1').AsCurrency))
      else
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('SubDescription').asstring,
          q.FieldByName('HappyHourPrice1').AsCurrency));

      if q.FieldByName('SubDescription1').asstring <> '' then
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('SubDescription1').asstring,
          q.FieldByName('HappyHourPrice2').AsCurrency));

      if q.FieldByName('SubDescription2').asstring <> '' then
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('SubDescription2').asstring,
          q.FieldByName('HappyHourPrice3').AsCurrency));

      if q.FieldByName('SubDescription3').asstring <> '' then
        PriceList.Add(TPair<String, Currency>.Create
          (q.FieldByName('SubDescription3').asstring,
          q.FieldByName('HappyHourPrice4').AsCurrency));
    end;
  end;
end;

{$ENDREGION}
{$REGION 'TTablePageList'}

procedure TTablePageList.SelectATable(PageNo: integer; TableNo: string);
begin
  self.SelectedPageNo := PageNo;
  self.SelectedTableNo := TableNo;
end;

constructor TTablePageList.Create;
begin
  self.FTablePageList := TList<TTablePage>.Create;
  LoadPages;
  LoadTables;
end;

procedure TTablePageList.LoadPages;
var
  q: TSQLQuery;
begin
  q := DataModule1.GetTablePages;
  while not q.eof do
  begin
    FTablePageList.Add(TTablePage.Create(q.FieldByName('PageNo').AsInteger,
      q.FieldByName('Description').asstring));
    q.Next;
  end;
  q.Close;
end;

procedure TTablePageList.LoadTables;
var
  q: TSQLQuery;
  PropertyFlag: integer;
begin
  q := DataModule1.GetTableLayout;
  while not q.eof do
  begin
{$IFDEF MSSQL}
    if q.FieldByName('PropertyFlag').AsBoolean then
      PropertyFlag := 1
    else
      PropertyFlag := 0;

    GetTablePageItem(q.FieldByName('pageflag').AsInteger)
      .Tables.Add(TTable.Create(q.FieldByName('TableNo').asstring, '',
      // q.FieldByName('OrderNo').AsString,
      q.FieldByName('Description').asstring, q.FieldByName('pageFlag')
      .AsInteger, q.FieldByName('ButtonX').AsInteger, q.FieldByName('ButtonY')
      .AsInteger, q.FieldByName('ButtonWidth').AsInteger,
      q.FieldByName('ButtonHeight').AsInteger, q.FieldByName('ButtonShape')
      .AsInteger, PropertyFlag));

{$ELSE}
    GetTablePageItem(q.FieldByName('pageflag').AsInteger)
      .Tables.Add(TTable.Create(q.FieldByName('TableNo').asstring, '',
      q.FieldByName('Description').asstring, q.FieldByName('pageFlag')
      .AsInteger, q.FieldByName('ButtonX').AsInteger, q.FieldByName('ButtonY')
      .AsInteger, q.FieldByName('ButtonWidth').AsInteger,
      q.FieldByName('ButtonHeight').AsInteger, q.FieldByName('ButtonShape')
      .AsInteger, q.FieldByName('PropertyFlag').AsInteger));
{$ENDIF}
    q.Next;
  end;
  q.Close;
end;

function TTablePageList.GetTablePageItem(PageNo: integer): TTablePage;
var
  i: integer;
begin
  result := FTablePageList[0];
  for i := 0 to FTablePageList.Count - 1 do
    if FTablePageList[i].PageNo = PageNo then
    begin
      result := FTablePageList[i];
      break;
    end;
end;

{$ENDREGION}
{$REGION 'TTable'}

constructor TTable.Create(TableNo, OrderNo, Description: string;
  PageNo, X, Y, Width, Height, Shape: integer; PropertyFlag: integer);
begin
  inherited Create;
  self.FTableNo := TableNo;
  self.FOrderNo := OrderNo;
  self.FShape := Shape;
  self.FX := X;
  self.FY := Y;
  self.FWidth := Width;
  self.FHeight := Height;
  self.FDescription := Description;

  FIsTable := (PropertyFlag = 1);

end;

{$ENDREGION}
{$REGION 'Customer Search'}

constructor TCustomer.Create(VipNo: string; VipName: string; tele: string;
  streetno: string; address: string; suburb: string; postcode: string);
begin
  inherited Create;

  self.FVipNo := VipNo;
  self.FVipName := VipName;
  self.ftele := tele;
  self.streetno := streetno;
  self.address := address;
  self.suburb := suburb;
  self.postcode := postcode;

end;



Constructor TCustomerInfo.Create;
var
  q: TSQLQuery;
begin
  inherited Create;
  q := DataModule1.GetVIPTable;
  self.CustomerList := TList<TCustomer>.Create;
  while not q.eof do
  begin
    CustomerList.Add(TCustomer.Create(q.FieldByName('VIPNo').asstring,
      q.FieldByName('VIPName').asstring, q.FieldByName('Telephone').asstring,
      q.FieldByName('Number').asstring, q.FieldByName('Address').asstring,
      q.FieldByName('Suburb').asstring, q.FieldByName('PostCode').asstring));
      q.next;
  end;
  q.close;
end;
destructor TCustomerInfo.Destroy;
begin
   CustomerList.Free;
   inherited Destroy;
end;

{$ENDREGION}
{$REGION 'TTablePage'}

constructor TTablePage.Create(PageNo: integer; Description: string);
begin
  inherited Create;
  self.FPageNo := PageNo;
  self.FDescription := Description;
  self.FTables := TList<TTable>.Create;
end;

{$ENDREGION}
{$REGION 'TProfile'}

constructor TProfile.Create;
var
  q: TSQLQuery;
  weekday: integer;
  settings: TFormatSettings;
begin
  q := DataModule1.GetProfile;
  self.RoundingFlag := q.FieldByName('RoundingFlag').AsInteger;
  self.ServiceChargeRate := q.FieldByName('ServiceChargeRate').AsFloat;

{$IFDEF MSSQL}
  self.ForceVIPDiscount := q.FieldByName('ForceVIPDiscount').AsBoolean;
  self.NotAllowModify := q.FieldByName('NotAllowModify').AsBoolean;
  self.HappyHour := q.FieldByName('HappyHour').AsBoolean;
  self.EnableWeekendPriceFunction := q.FieldByName('EnableWeekendPriceFunction')
    .AsBoolean;
  self.HappyHourStartTime := q.FieldByName('HappyHourStartTime').AsDateTime;
  self.HappyHourEndTime := q.FieldByName('HappyHourEndTime').AsDateTime;
{$ELSE}
  settings.DateSeparator := '-';
  settings.TimeSeparator := ':';
  settings.ShortDateFormat := 'yyyy-mm-dd';
  settings.ShortTimeFormat := 'hh:nn:ss';

  self.ForceVIPDiscount := (q.FieldByName('ForceVIPDiscount').AsInteger = 1);
  self.NotAllowModify := (q.FieldByName('NotAllowModify').AsInteger = 1);
  self.HappyHour := (q.FieldByName('HappyHour').AsInteger = 1);
  self.EnableWeekendPriceFunction :=
    (q.FieldByName('EnableWeekendPriceFunction').AsInteger = 1);
  self.HappyHourStartTime := StrToDateTime(q.FieldByName('HappyHourStartTime')
    .asstring, settings);
  self.HappyHourEndTime := StrToDateTime(q.FieldByName('HappyHourEndTime')
    .asstring, settings);
{$ENDIF}
  if HappyHour and (Now >= HappyHourStartTime) and (Now <= HappyHourEndTime)
  then
    self.FPriceType := TPriceType.HappyHour // happyhour high priority
  else
  begin
    weekday := DayOfWeek(Now) - 1;
    if EnableWeekendPriceFunction and
      (weekday >= q.FieldByName('WeekendPriceStartDay').AsInteger) and
      (weekday <= q.FieldByName('WeekendPriceEndDay').AsInteger) then
      self.FPriceType := TPriceType.Weekend
    else
      self.FPriceType := TPriceType.Normal;
  end;
  q.Close;
end;
{$ENDREGION}
{$REGION 'TMenuInstructionLink'}

constructor TMenuInstructionLink.Create(q: TSQLQuery);
begin
  self.ParentCode := q.FieldByName('ItemCode').asstring;
  self.ChildCode := q.FieldByName('SubMenuCode').asstring;
  self.SalesPrice := q.FieldByName('SalesPrice').AsFloat;
  self.SalesQty := q.FieldByName('SalesQty').AsFloat;
  self.Description := q.FieldByName('Description1').asstring;
{$IFDEF MSSQL}
  self.Instruction := q.FieldByName('Instruction').AsBoolean;
  self.ChoiceItem := q.FieldByName('ChoiceItem').AsBoolean;
  self.MaximunCharge := q.FieldByName('MaximunCharge').AsBoolean;
{$ELSE}
  self.Instruction := q.FieldByName('Instruction').AsInteger = 1;
  self.ChoiceItem := q.FieldByName('ChoiceItem').AsInteger = 1;
  self.MaximunCharge := q.FieldByName('MaximunCharge').AsInteger = 1;
{$ENDIF}
end;

// class function TMenuInstructionLink.GetMenuInstructionLinkList:TList<TMenuInstructionLink>;
// var
// list : TList<TMenuInstructionLink>;
// q : TSQLQuery;
// begin
// list := TList<TMenuInstructionLink>.Create;
// q := DataModule.GetMenuInstructionLink;
// while not q.eof do
// begin
// list.Add(TMenuInstructionLink.Create(q));
// q.Next;
// end;
// q.Close;
// result := list;
// end;

{$ENDREGION}

end.
